#ifndef __CORE_LOG_H__
#define __CORE_LOG_H__
#include <iostream>
#include <chrono>
#include <time.h>
#include<stdio.h>
#include "core_task.h"
#include "core_log.h"

class CoreLog
{
private:
	CoreTask task;
	FILE* file;
private:
	void close()
	{
		if (this->file)
		{
			fclose(this->file);
			this->file = nullptr;
		}
	}
public:
	CoreLog()
	{
		task.start();
	}
	virtual ~CoreLog()
	{
		task.stop();
		this->close();
	}
public:
	static CoreLog* getInstance()
	{
		static CoreLog c;
		return &c;
	}
	void setLogPath(const char* logPath, const char* mode)
	{
		this->close();
		this->file = fopen(logPath, mode);
		if (this->file)
		{
			this->info("CoreLog::setLogPath sucess (%s,%s)", logPath, mode);
		}
		else
		{
			this->info("CoreLog::setLogPath failed (%s,%s)", logPath, mode);
		}
	}
	void info(const char* pStr)
	{
		CoreLog* log = getInstance();
		log->task.addTask([=]() {
			if (log->file)
			{
				time_t timep;
				time(&timep);
				struct tm *now = gmtime(&timep);
				//fprintf(log->file, "[%d-%d-%d %d:%02d:%02d] %s %s\n", now->tm_year + 1900, now->tm_mon + 1, now->tm_mday, now->tm_hour + 8, now->tm_min, now->tm_sec, "INFO", pStr);
				//fflush(log->file);
				std::string s = string_sprintf("%d-%d-%d %d:%02d:%02d %s %s\n", now->tm_year + 1900, now->tm_mon + 1, now->tm_mday, now->tm_hour + 8, now->tm_min, now->tm_sec, "INFO", pStr);
				fputs(s.c_str(), log->file);
				fflush(log->file);
				std::cout << s.c_str();
			}
			});
	}

	template<typename ...Args>
	void info(const char* pformat, Args ... args)
	{
		CoreLog* log = getInstance();
		log->task.addTask([=]() {
			if (log->file)
			{
				auto t = std::chrono::system_clock::now();
				auto tNow = std::chrono::system_clock::to_time_t(t);
				std::tm* now = gmtime(&tNow);
				//fprintf(log->file, "[%d-%d-%d %d:%02d:%02d] %s ", now->tm_year + 1900, now->tm_mon + 1, now->tm_mday, now->tm_hour + 8, now->tm_min, now->tm_sec,"INFO");
				std::string s1 = string_sprintf("%d-%d-%d %d:%02d:%02d %s ", now->tm_year + 1900, now->tm_mon + 1, now->tm_mday, now->tm_hour + 8, now->tm_min, now->tm_sec, "INFO");
				std::string s2 = string_sprintf(pformat, args...);
				s1 += s2;
				s1 += "\n";
				fputs(s1.c_str(), log->file);
				fflush(log->file);
				std::cout << s1.c_str();
			}
			});
	}

	template< typename... Args >
	std::string string_sprintf(const char* format, Args... args) {
		int length = std::snprintf(nullptr, 0, format, args...);
		if (length <= 0) {
			return "";
		}
		char* buf = new char[length + 1];
		std::snprintf(buf, length + 1, format, args...);

		std::string str(buf);
		delete[] buf;
		return std::move(str);
	}

};



#endif